package com.example.security6atguigu.config;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.security6atguigu.entity.User;
import com.example.security6atguigu.mapper.UserMapper;
import com.example.security6atguigu.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsPasswordService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collection;

@Component
public class DBUserDetailsManager implements UserDetailsManager, UserDetailsPasswordService {
    @Resource
    private UserMapper userMapper;

    /**
     * 跟新数据库中用户密码
     * @param userDetails UserDetails[在构造userDetails将新密码设置进去，所以这里取出来的就是新的加密密码]
     * @param newPassword 新密码[原始密码]
     * @return UserDetails
     */
    @Override
    public UserDetails updatePassword(UserDetails userDetails, String newPassword) {

        UserDetails userDetails1 = org.springframework.security.core.userdetails.User.builder()
                .username(userDetails.getUsername())
                .password(newPassword) // 使用新密码
                .authorities(userDetails.getAuthorities()) // 保持原有的权限
                .accountExpired(userDetails.isAccountNonExpired()) // 复制账户是否过期的状态
                .accountLocked(userDetails.isAccountNonLocked()) // 复制账户是否锁定的状态
                .credentialsExpired(userDetails.isCredentialsNonExpired()) // 复制凭证是否过期的状态
                .disabled(userDetails.isEnabled()) // 复制账户是否禁用的状态
                .build();

        return userDetails1;
    }

    /**
     * 向数据库中添加用户信息
     * @param userDetails UserDetails
     */
    @Override
    public void createUser(UserDetails userDetails) {
        User user = new User();
        user.setUsername(userDetails.getUsername());
        user.setPassword(userDetails.getPassword());
        System.out.println(userDetails.isEnabled()?1:0);
        user.setEnabled(userDetails.isEnabled()?1:0);
        userMapper.insert(user);
    }

    @Override
    public void updateUser(UserDetails userDetails) {
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, userDetails.getUsername()));
        user.setPassword(userDetails.getPassword());
        userMapper.updateById(user);
    }

    @Override
    public void deleteUser(String username) {

    }

    @Override
    public void changePassword(String oldPassword, String newPassword) {

    }

    @Override
    public boolean userExists(String username) {
        return false;
    }

    /**
     * 从数据库中获取用户信息
     * @param username 用户名
     * @return  UserDetails
     * @throws UsernameNotFoundException    用户名不存在异常
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
        if (user == null) {
            throw new UsernameNotFoundException(username);
        }else {
            /*
            Collection<GrantedAuthority> authorities = new ArrayList<>();
            // 在这里对用户的权限信息进行硬编码，实际项目中应该从数据库中获取权限信息
//            authorities.add(() -> "USER_LIST");
            authorities.add(() -> "USER_ADD");
            return new org.springframework.security.core.userdetails.User(
                    user.getUsername(),
                    user.getPassword(),
                    user.getEnabled() == 1,
                    true,// 用户账号是否未过期
                    true,// 用户凭证是否过期
                    true,// 用户是否未被锁定
                    authorities// 用户的权限列表
            );

             */

            return org.springframework.security.core.userdetails.User
                    .withUsername(user.getUsername())
                    .password(user.getPassword())
                    .disabled(!(user.getEnabled() == 1))
                    .credentialsExpired(false)
                    .accountLocked(false)
                    .roles("admin")
                    .build();
        }
    }
}
